// MultiStepper
// -*- mode: C++ -*-
//
// Control both Stepper motors at the same time with different speeds
// and accelerations. 
// Requires the AFMotor library (https://github.com/adafruit/Adafruit-Motor-Shield-library)
// And AccelStepper with AFMotor support (https://github.com/adafruit/AccelStepper)
// Public domain!

#define FRONT_WAITING 0
#define TIME_TRACKING 1

unsigned long time;
long loopCounter;

const int referenceVoltageInPin = A0;  // Analog input pin that the potentiometer is attached to
const int pulseOutPin = 3; // Analog output pin that the LED is attached to
const int frontLevel = 1000; // уровень переднего фронта положительной полуволны переменного напряжения, к которому привязывается опорный импульс. 
const int pulseWidth = 100; // ширина управляющего импульса (в микросекундах)

int sensorValue = 0;        // value read from the pot
int outputValue = 0;        // value output to the PWM (analog out)
int prevSensorValue = 0; // предыдущее мнгновенное значение опорного напряжения
unsigned long frontTime = 0; // время достижения опорного фронта переменного напряжения (в микросекундах) относительно момента начала работы программы
unsigned int pulseShift = 0; // временной сдвиг управляющего импульса относительно опорного фронта (в микросекундах)


byte controlState = FRONT_WAITING;

void setup()
{  
  pinMode(pulseOutPin, OUTPUT);

 
  Serial.begin(9600);
  time = micros();
  loopCounter = 0;
  digitalWrite(pulseOutPin, 0);   
}

int i = 0;
int inChar;
String inString = "";

void sendState()
{

  char s[255] = "time:";
  char s1[11] = "";
  ltoa(micros(), s1, 10);
  strcat( s, s1 );
  strcat(s,";cycle:");
  ltoa(loopCounter, s1, 10);
  strcat( s, s1 );
  strcat (s,";");
  Serial.flush();
  Serial.println( s ); 
}


void loop()
{
  loopCounter++;
  /*if (micros() - time > 1000)
   {
     sendState();
     time = micros();
   }
   */

   if (controlState == FRONT_WAITING) // если схема находится в состоянии ожидания переднего фронта опорного переменного напряжения 
   {
     sensorValue = analogRead( referenceVoltageInPin ); // считываем мгновенное значение опорного переменного напряжения (400 Гц) (10 бит 0..1023) 
     if ( sensorValue > frontLevel && prevSensorValue <= frontLevel) // проверяем, не достигнут ли заданный уровень положительной полуволны переменного напряжения   
     {
       frontTime = micros();  // запоминаем момент времени достиженния уровня фронта
       controlState = TIME_TRACKING;   // переходим в состояние слежения за временем
       prevSensorValue = 0; // сбрасываем предудыщее значение напряжения в 0
     }
     else
     {
       prevSensorValue = sensorValue;  // запоминаем текущее значение напряжения   
     }
   }
   else if (controlState == TIME_TRACKING)
   {
     if ( micros() - frontTime >= pulseShift ) // если достигнут заданный временной сдвиг управляющего импульса относительно опорного
     {
         digitalWrite(pulseOutPin, 1); // формируем управляющий импульс
         delayMicroseconds(pulseWidth);
         digitalWrite(pulseOutPin, 0);     
         controlState = FRONT_WAITING; // переходим в состояние ожидания следующего фронта  
     }
   }
    
}




